package com.gexiaobao.pigeon.ui.pilot.fragment

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import com.amap.api.location.AMapLocation
import com.amap.api.location.AMapLocationClient
import com.amap.api.location.AMapLocationClientOption
import com.amap.api.location.AMapLocationListener
import com.amap.api.services.core.LatLonPoint
import com.amap.api.services.geocoder.GeocodeResult
import com.amap.api.services.geocoder.GeocodeSearch
import com.amap.api.services.geocoder.RegeocodeQuery
import com.amap.api.services.geocoder.RegeocodeResult
import com.amap.api.services.weather.LocalWeatherForecastResult
import com.amap.api.services.weather.LocalWeatherLive
import com.amap.api.services.weather.LocalWeatherLiveResult
import com.amap.api.services.weather.WeatherSearch
import com.amap.api.services.weather.WeatherSearchQuery
import com.gexiaobao.pigeon.R
import com.gexiaobao.pigeon.app.App
import com.gexiaobao.pigeon.app.base.BaseFragment
import com.gexiaobao.pigeon.app.model.bean.RaceDetailInfoResponse
import com.gexiaobao.pigeon.app.model.param.NextPassParams
import com.gexiaobao.pigeon.app.model.param.StartFlyParams
import com.gexiaobao.pigeon.app.util.RxToast
import com.gexiaobao.pigeon.databinding.FragmentTrainingMissionBinding
import com.gexiaobao.pigeon.ui.dialog.AlertDialog
import com.gexiaobao.pigeon.ui.dialog.RxDialogDefault
import com.gexiaobao.pigeon.ui.fragment.mine.organization.detail.FragmentOrgCompetition
import com.gexiaobao.pigeon.viewmodel.ReleaseMissionViewModel
import me.hgj.jetpackmvvm.ext.util.setOnclickNoRepeat
import java.text.SimpleDateFormat
import java.util.Date

/**
 * @Author      : hxw
 * @Date        : 2023/6/1 11:36
 * @Describe    : 放飞任务
 */
class FragmentTrainingMission : BaseFragment<ReleaseMissionViewModel, FragmentTrainingMissionBinding>(), AMapLocationListener,
    GeocodeSearch.OnGeocodeSearchListener, WeatherSearch.OnWeatherSearchListener {

    private var dataResult = RaceDetailInfoResponse()

    private var mId = ""
    private var mPassType = 0
    private var mPassStatus = 0

    //高德地图定位相关
    private lateinit var mLocationClient: AMapLocationClient
    private lateinit var mLocationOption: AMapLocationClientOption

    //定位结果
    private lateinit var mapLocation: AMapLocation

    //城市查询
    lateinit var geoCoderSearch: GeocodeSearch
    lateinit var reGeoCodeResult: RegeocodeResult
    private lateinit var cancelDialog: AlertDialog

    //查询实时天气相关
    private lateinit var weatherlive: LocalWeatherLive
    private lateinit var weatherSearchQuery: WeatherSearchQuery
    private lateinit var weatherSearch: WeatherSearch

    private var mFlyTime: String = ""

    override fun initView(savedInstanceState: Bundle?) {
        mId = requireArguments().getString("id").toString()
        mPassType = requireArguments().getInt("passType", 0)
        mPassStatus = requireArguments().getInt("passStatus", 0)

        mDatabind.viewmodel = mViewModel
        //隐私合规检查
        AMapLocationClient.updatePrivacyShow(context, true, true)
        AMapLocationClient.updatePrivacyAgree(context, true)
        weatherlive = LocalWeatherLive()
    }

    override fun initData() {
        super.initData()
        cancelDialog = context?.let {
            AlertDialog(it).builder()
                .setMsg("正在获取位置等信息...")
                .setCancelable(false)
                .setNegativeButton("请稍后") {}
        }!!
    }

    override fun lazyLoadData() {
        super.lazyLoadData()
        showLoading(getString(R.string.loading))
        mViewModel.getPassDetailApp(mId)
    }

    override fun createObserver() {
        super.createObserver()
        mViewModel.detailInfoResult.observe(viewLifecycleOwner) {
            if (it != null) {
                dismissLoading()
                mDatabind.data = it
                dataResult = it
                refreshUI(it)
            }
        }
        mViewModel.startRacingResult.observe(viewLifecycleOwner) {
            if (it.isSuccess) {
                RxToast.showToast("操作成功")
                showLoading(getString(R.string.loading))
                mViewModel.getPassDetailApp(mId)
            } else {
                RxToast.showToast(it.errorMsg)
            }
        }

        mViewModel.nextResult.observe(viewLifecycleOwner) {
            if (it.isSuccess) {
                RxToast.showToast("操作成功")
                showLoading(getString(R.string.loading))
                mViewModel.getPassDetailApp(mId)
            } else {
                RxToast.showToast(it.errorMsg)
            }
        }
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private fun refreshUI(it: RaceDetailInfoResponse) {
        mPassType = it.passType
        mPassStatus = it.passStatus
        if (it.passType == 2) {//训放
            when (it.passStatus) {
                2 -> {//报名中
                    mViewModel.startFly.set("结束报名")
                    mDatabind.llBottomBtnFly.visibility = View.VISIBLE
                }

                3 -> {//报名结束
                    mViewModel.startFly.set("开始放飞")
                    mDatabind.llBottomBtnFly.visibility = View.VISIBLE
                }

                else -> {
                    mDatabind.llBottomBtnFly.visibility = View.GONE
                }
            }
        } else {//比赛
            when (it.passStatus) {
                5 -> {
                    mViewModel.startFly.set("开始放飞")
                    mDatabind.llBottomBtnFly.visibility = View.VISIBLE
                }

                6, 7, 8, 9, 10 -> {
                    mDatabind.llBottomBtnFly.visibility = View.VISIBLE
                    mViewModel.startFly.set("放飞已结束")
                    mDatabind.tvTrainingMissionStartFly.isClickable = false
                    mDatabind.tvTrainingMissionStartFly.setBackgroundResource(R.drawable.round_btn_gray25_b_g)
                }

                else -> {
                    mDatabind.llBottomBtnFly.visibility = View.GONE
                }
            }
        }
    }

    override fun onBindViewClick() {
        super.onBindViewClick()
        setOnclickNoRepeat(mDatabind.tvTrainingMissionStartFly) {
            when (it) {
                mDatabind.tvTrainingMissionStartFly -> {
                    if (mPassType == 2) {//训放
                        when (mPassStatus) {
                            2 -> {//报名中-结束报名
                                showLoading(getString(R.string.loading))
                                val bodyStopSign = NextPassParams(passId = mId.toInt())
                                mViewModel.getNext(bodyStopSign)
                            }

                            3 -> {//报名结束-开始放飞
                                showFlyDialog()
                            }
                        }
                    } else {
                        showFlyDialog()
                    }
                }
            }
        }
    }

    companion object {

        fun newInstance(id: String, passType: Int, passStatus: Int): FragmentTrainingMission {
            val fragment = FragmentTrainingMission()
            val bundle = Bundle()
            bundle.putInt("passType", passType)
            bundle.putInt("passStatus", passStatus)
            bundle.putString("id", id)
            fragment.arguments = bundle
            return fragment
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun location(locationMode: AMapLocationClientOption.AMapLocationMode) {
        //初始化定位
        mLocationClient = AMapLocationClient(App.instance)
        //设置定位回调监听
        if (locationMode == AMapLocationClientOption.AMapLocationMode.Device_Sensors) {
            mLocationClient.setLocationListener { aMapLocation: AMapLocation? ->
                if (aMapLocation != null) {
                    if (aMapLocation.errorCode == 0) {
                        mapLocation = aMapLocation
                        //定位成功回调信息，设置相关消息
                        aMapLocation.locationType//获取当前定位结果来源，如网络定位结果，详见官方定位类型表
                        val la = aMapLocation.latitude//获取纬度
                        val lo = aMapLocation.longitude//获取经度
                        aMapLocation.accuracy//获取精度信息
                        val df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                        val date = Date(aMapLocation.time)
                        mFlyTime = df.format(date)//定位时间
                        geoCoderSearch = GeocodeSearch(context)
                        geoCoderSearch.setOnGeocodeSearchListener(this)
                        val query = RegeocodeQuery(LatLonPoint(la, lo), 200.0F, GeocodeSearch.AMAP)
                        geoCoderSearch.getFromLocationAsyn(query)
                    } else {
                        if (aMapLocation.errorCode == 14) {
                            context?.let {
                                AlertDialog(it).builder()
                                    .setMsg(getString(R.string.train_fly_detail_detail_fragment_alert_gps_low_msg))
                                    .setNegativeButton(getString(R.string.train_fly_detail_detail_fragment_alert_gps_low_turn_net)) {
                                        showLoading(getString(R.string.train_fly_detail_detail_fragment_alert_gps_low_show_loading_dialog_msg))
                                        location(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy)
                                    }
                                    .setPositiveButton(getString(R.string.train_fly_detail_detail_fragment_alert_gps_low_turn_cancel)) {}
                                    .setCancelable(false).show()
                            }
                            if (cancelDialog.dialog!!.isShowing) cancelDialog.dialog!!.dismiss()
                        } else {
                            alertAndDismissDialog("${aMapLocation.errorCode}:" + getString(R.string.train_fly_detail_detail_fragment_alert_gps_err_walk_out_retry))
                        }
                    }
                } else {
                    alertAndDismissDialog(getString(R.string.train_fly_detail_detail_fragment_alert_gps_err_walk_out_retry))
                }
            }
        } else {
            mLocationClient.setLocationListener(this)
        }
        //初始化定位参数
        mLocationOption = AMapLocationClientOption()
        //设置定位模式为Hight_Accuracy高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
//        mLocationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy
        mLocationOption.locationMode = locationMode
        //设置是否返回地址信息（默认返回地址信息）
        mLocationOption.isNeedAddress = true
        //设置是否强制刷新WIFI，默认为强制刷新
        mLocationOption.isWifiActiveScan = true
        //设置是否允许模拟位置,默认为false，不允许模拟位置
        mLocationOption.isMockEnable = true
        //设置定位间隔,单位毫秒,默认为2000ms
        mLocationOption.interval = 2000
        //设置是否只定位一次,默认为false
        mLocationOption.isOnceLocation = true

        //获取最近3s内精度最高的一次定位结果：
//      设置setOnceLocationLatest(boolean b)接口为true，启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true，setOnceLocation(boolean b)接口也会被设置为true，反之不会，默认为false。
        mLocationOption.isOnceLocationLatest = true
//      关闭缓存机制
//        mLocationOption.setLocationCacheEnable(false).
        //单位是毫秒，默认30000毫秒，建议超时时间不要低于8000毫秒。
        mLocationOption.httpTimeOut = 10000
        mLocationOption.gpsFirstTimeout = 10000
        //给定位客户端对象设置定位参数
        mLocationClient.setLocationOption(mLocationOption)
        //启动定位
        mLocationClient.startLocation()
    }

    private fun alertAndDismissDialog(msg: String) {
        context?.let {
            AlertDialog(it).builder().setMsg(msg)
                .setNegativeButton(getString(R.string.ok)) {}.setCancelable(false).show()
        }
        if (cancelDialog.dialog?.isShowing == true) cancelDialog.dialog!!.dismiss()
    }

    @SuppressLint("SimpleDateFormat")
    override fun onLocationChanged(aMapLocation: AMapLocation?) {
        if (aMapLocation != null) {
            if (aMapLocation.errorCode == 0) {
                mapLocation = aMapLocation
                //定位成功回调信息，设置相关消息
                aMapLocation.locationType//获取当前定位结果来源，如网络定位结果，详见官方定位类型表
                val la = aMapLocation.latitude//获取纬度
                val lo = aMapLocation.longitude//获取经度
                aMapLocation.accuracy//获取精度信息
                val df = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                val date = Date(aMapLocation.time)
                mFlyTime = df.format(date)//定位时间
                geoCoderSearch = GeocodeSearch(context)
                geoCoderSearch.setOnGeocodeSearchListener(this)
                val query = RegeocodeQuery(LatLonPoint(la, lo), 200.0F, GeocodeSearch.AMAP)
                geoCoderSearch.getFromLocationAsyn(query)
            } else {
                if (aMapLocation.errorCode == 14) {
                    context?.let {
                        AlertDialog(it).builder()
                            .setMsg(getString(R.string.train_fly_detail_detail_fragment_alert_gps_low_msg))
                            .setNegativeButton(getString(R.string.train_fly_detail_detail_fragment_alert_gps_low_turn_net)) {
                                showLoading(getString(R.string.train_fly_detail_detail_fragment_alert_gps_low_show_loading_dialog_msg))
                                location(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy)
                            }
                            .setPositiveButton(getString(R.string.train_fly_detail_detail_fragment_alert_gps_low_turn_cancel)) {}
                            .setCancelable(false).show()
                    }
                } else {
                    alertAndDismissDialog("${aMapLocation.errorCode}:" + getString(R.string.train_fly_detail_detail_fragment_alert_gps_err_walk_out_retry))
                }
            }
        } else {
            alertAndDismissDialog(getString(R.string.train_fly_detail_detail_fragment_alert_gps_err_walk_out_retry))
        }
    }

    override fun onRegeocodeSearched(result: RegeocodeResult?, rCode: Int) {
        if (rCode == 1000 && result != null) {
            reGeoCodeResult = result
            queryWeather(result.regeocodeAddress.city)
        } else {
            alertAndDismissDialog(getString(R.string.train_fly_detail_detail_fragment_location_city_err))
        }
    }

    private fun queryWeather(city: String?) {
        weatherSearchQuery = WeatherSearchQuery(city, WeatherSearchQuery.WEATHER_TYPE_LIVE)
        weatherSearch = WeatherSearch(context)
        weatherSearch.setOnWeatherSearchListener(this)
        weatherSearch.query = weatherSearchQuery
        weatherSearch.searchWeatherAsyn()
    }

    override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {}

    override fun onWeatherLiveSearched(weatherLiveResult: LocalWeatherLiveResult?, rCode: Int) {
        if (rCode == 1000) {
            if (weatherLiveResult?.liveResult != null) {
                weatherlive = weatherLiveResult.liveResult
                val buffer = StringBuffer()
                buffer.append(
                    weatherlive.reportTime + "发布 " + " ===\n " +
                            weatherlive.weather + " === " +
                            weatherlive.temperature + "°" + " === " +
                            weatherlive.windDirection + "风向  " + " === " +
                            weatherlive.windPower + "级" + " === " +
                            "湿度 :" + weatherlive.humidity + "%"
                )
                requestStartTraining(weatherlive)
            } else {
                alertAndDismissDialog(getString(R.string.train_fly_detail_detail_fragment_weather_err_go_out_retry))
            }
        } else {
            alertAndDismissDialog("$rCode" + getString(R.string.train_fly_detail_detail_fragment_weather_err_go_out_retry))
        }
    }

    private fun requestStartTraining(weatherLive: LocalWeatherLive?) {
        if (cancelDialog.dialog!!.isShowing) cancelDialog.dialog!!.dismiss()
        val body = StartFlyParams(
            passId = mId.toInt(),
            flyLon1 = mapLocation.longitude,
            flyLat1 = mapLocation.latitude,
            flyTime = mFlyTime,
            flyPlace = reGeoCodeResult.regeocodeAddress.formatAddress,
            weather = weatherLive!!.weather,
            windPower = weatherLive.windPower,
            windDirection = weatherLive.windDirection
        )
        showLoading(getString(R.string.loading))
        mViewModel.startRacing(body)
    }

    private fun showFlyDialog() {
        val dialog = RxDialogDefault(context)
        dialog.setTitle("确定要开启此次放飞任务吗")
        dialog.setSureListener {
            dialog.dismiss()
            cancelDialog.show()
            location(AMapLocationClientOption.AMapLocationMode.Device_Sensors)
        }
        dialog.setFullScreenWidth()
        dialog.show()
    }

    override fun onWeatherForecastSearched(p0: LocalWeatherForecastResult?, p1: Int) {
    }
}